const fs = require("fs-extra");
const path = require("path");
const Generator = require("./Generator");
const logInfo = require('../../util/logInfo');
const logStep = require('../../util/logStep');
const { loadModule } = require("./utils/modules");
module.exports = async function (pluginName, pluginOptions, context) {
  logInfo("invoke 是添加插件的核心封装");
  logStep(
    "3. 对于通用插件来说调用这一步的关键在于验证插件的有效性，同时对于需要 prompts 的插件会执行插件的prompts参数，最后也会调用 runGenerator"
  );
  logStep("3.1 同时这一步还会组装 runGenerator 需要的参数格式");

  await runGenerator(context, {
    id: pluginName,
    apply: loadModule(pluginName, context),
    options: {
      pluginOptions,
    },
  });
};

function readFiles(context) {
  logInfo(
    "这里是很关键的一步，会读取当前文件夹下 node_modules 和忽略的文件之外的所有文件，提供给 generator， 而generator 再后续的构建过程中，则会修改需要修改的文件。"
  );

  return [];
}

async function runGenerator(context, plugin, pkg = getPkg(context)) {
  logInfo("invoke 是添加插件的核心封装");
  logInfo("这里基本上执行了 creator 里的插件安装步骤");
  logStep(
    "4. new Generator 执行与creator 中类似的构建过程，区别在于插件和是否已经存在构建文件"
  );
  logInfo(` const createCompleteCbs = [];
 const generator = new Generator(context, {
   pkg,
   plugins: [plugin],
   files: readFiles(),
   completeCbs: createCompleteCbs,
   invoking: true,
 });

 await generator.generate({
   extractConfigFiles: true,
   checkExisting: true,
 });`);

  logStep("4.2 构建完成后同样需要更新 pkg 文件");
}

function getPkg(context) {
  const pkgPath = path.resolve(context, "package.json");
  if (!fs.existsSync(pkgPath)) {
    throw new Error(`package.json not found in ${chalk.yellow(context)}`);
  }
  const pkg = fs.readJsonSync(pkgPath);
  if (pkg.vuePlugins && pkg.vuePlugins.resolveFrom) {
    return getPkg(path.resolve(context, pkg.vuePlugins.resolveFrom));
  }
  return pkg;
}

module.exports.runGenerator = runGenerator;
